package com.dreamana.components
{
	import com.dreamana.ui.BaseComponent;
	import com.dreamana.ui.ISkinnable;
	
	import flash.display.DisplayObject;
	import flash.display.Graphics;
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.ui.Keyboard;
	
	[Event(name="select", type="flash.events.Event")]

	public class ComboBox extends BaseComponent implements ISkinnable
	{
		protected var _input:TextInput;
		protected var _button:Button;
		protected var _buttonWidth:int;
		protected var _buttonHeight:int;
		protected var _buttonLabel:Shape;
		protected var _list:List;
		protected var _listWidth:int;
		protected var _listHeight:int;
		protected var _open:Boolean = false;
		
		public function ComboBox(w:int, h:int)
		{
			_width = w;
			_height = h;
			
			_buttonWidth = h;
			_buttonHeight = h;
			
			_listWidth = w;
			_listHeight = (ListCell.defaultFormat.size +8) * 8;//default list height
			
			this.init();
		}
		
		override protected function addChildren():void
		{
			//TextInput
			_input = new TextInput(_width, _height);
			_input.textField.selectable = false;
			_input.textField.mouseEnabled = false;
			this.addChild(_input);
			
			//Button
			_buttonLabel = new Shape();
			_button = new Button(_buttonWidth, _buttonHeight, _buttonLabel);
			_button.x = _width - _buttonWidth;
			this.addChild(_button);
						
			//Dropdown-list 
			_list = new List(_listWidth, _listHeight);
			
			_button.addEventListener(MouseEvent.CLICK, onDropDown);
			_input.addEventListener(MouseEvent.CLICK, onDropDown);
			_list.cellContainer.addEventListener(MouseEvent.CLICK, onListCellClick);
		}

		protected function removeList():void
		{
			_open = false;
			if(stage.contains(_list)) stage.removeChild(_list);
			stage.removeEventListener(MouseEvent.MOUSE_DOWN, onStageDown);
			stage.removeEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
		}
		
		protected function setLabel():void
		{
			_input.text = (_list.selectedItem)? _list.selectedItem["label"] : "";
		}
		
		//--- PUBLIC METHODS ---
		
		override public function draw():void
		{
			_input.setSize(_width, _height);
			
			_listWidth = _width;
			_list.setSize(_listWidth, _listHeight);
			
			_buttonWidth = _height;
			_buttonHeight = _height;
			_button.setSize(_buttonWidth, _buttonHeight);
			_button.x = _width - _buttonWidth;
			
			if(_button.label == _buttonLabel) {
				var g:Graphics = _buttonLabel.graphics;
				var ox:int = _buttonWidth/2;
				var oy:int = _buttonHeight/2;
				g.clear();
				g.beginFill(0x0);
				g.moveTo(0 +ox, 4 +oy);
				g.lineTo(4 +ox, -2 +oy);
				g.lineTo(-4 +ox, -2 +oy);
				g.lineTo(0 +ox, 4 +oy);
				g.endFill();
			}
		}
		
		override public function setStyle(style:String, value:Object):void
		{
			super.setStyle(style, value);
			
			switch(style) {
				case "list-height":
					_listHeight = value as Number;
					_list.setSize(_listWidth, _listHeight);
					break;
			}
		}
		
		public function setItems(list:Array):void
		{
			//var maxLines:int = 8;
			//var lines:int = Math.max(Math.min(list.length, maxLines), 1);
			//_list.height = _list.cellHeight * lines;

			_list.setItems(list);
			
			//this.setLabel();
		}
		
		public function selectItemByData(data:*):void
		{
			var index:int = -1;
			var a:Array = _list.items;
			var i:int = a.length;
			while(i--) {
				if(a[i]["data"] == data) {
					index = i;
					break;
				}
			}
			
			this.selectedIndex = index;
		}
		
		//--- EVENT HANDLERS ---
		
		protected function onDropDown(e:MouseEvent):void
		{
			_open = !_open;
			if(_open) {
				//openList()
				var pt:Point = this.localToGlobal(new Point(0, _height));
				_list.x = pt.x;
				_list.y = pt.y;
				stage.addChild(_list);
			
				stage.addEventListener(MouseEvent.MOUSE_DOWN, onStageDown);
				stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
			}
			else {
				removeList();
			}
		}
		
		protected function onStageDown(e:MouseEvent):void
		{
			var target:DisplayObject = e.target as DisplayObject;
			if(this.contains(target) || _list.contains(target)) return;
			
			removeList();
		}
		
		protected function onListCellClick(e:Event):void
		{
			setLabel();
			
			//remove list
			removeList();
			
			//TODO:CHANGE EVENT
			
			//dispatch
			this.dispatchEvent(new Event(Event.SELECT));
		}
		
		protected function onKeyDown(event:KeyboardEvent):void
		{
			switch(event.keyCode)
			{
				case Keyboard.UP:
					if(_list.selectedIndex > 0) _list.selectedIndex--;
					else _list.selectedIndex = _list.items.length-1;
					this.setLabel();
					break;
				
				case Keyboard.DOWN:
					if(_list.selectedIndex < _list.items.length-1) _list.selectedIndex++;
					else _list.selectedIndex = 0;
					this.setLabel();
					break;
				
				case Keyboard.ENTER:
					onListCellClick(null);
					break;
			}
		}
		
		//--- GETTER/SETTERS ---
		
		public function get selectedIndex():int { return _list.selectedIndex; }
		public function set selectedIndex(value:int):void {
			_list.selectedIndex = value;
			setLabel();
		}
		
		public function get selectedItem():Object { return _list.selectedItem; }
		
		public function get input():TextInput { return _input; }
		public function get button():Button { return _button; }
		public function get dropDownList():List { return _list; }
		
		public function get editable():Boolean { return _input.textField.selectable; }
		public function set editable(value:Boolean):void {
			_input.textField.selectable = value;
			_input.textField.mouseEnabled = value;
			
			if(value) _input.removeEventListener(MouseEvent.CLICK, onDropDown);
			else _input.addEventListener(MouseEvent.CLICK, onDropDown);
		}
	}
}